package com.backstage.configuration.shiro;

import com.backstage.common.LoginException;
import com.backstage.common.uitil.DES_3;
import com.backstage.entity.User;
import com.backstage.service.LoginService;
import com.backstage.service.UserService;
import com.backstage.service.impl.UserServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @Project authority
 * @Package com.backstage.configuration
 * @Data 2017/7/11下午 5:22.
 * @Aurhor 阮雪峰
 */
@Component("realm")
public class AuthorityRealm extends AuthorizingRealm {

    @Resource(name = "loginService")
    private LoginService loginService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        User user = (User)principalCollection.fromRealm("authorityRealm").iterator().next();
        List<String> permission_list = new ArrayList<>();
        if(user != null){
            permission_list.addAll(loginService.queryUserPermission(user));
        }
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.addStringPermissions(permission_list);
        return authorizationInfo;
    }

    /**
     * 登录验证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        CustomToken token = (CustomToken)authenticationToken;
        String username = token.getUsername();//(String) authenticationToken.getPrincipal();//获取用户名
        char[] c = token.getPassword();//authenticationToken.getCredentials() == null ? new char[0]:((char[]) authenticationToken.getCredentials());
        String password = new String(c);//获取密码
        String verifyCode = token.getVerifyCode();
        String rand = (String) SecurityUtils.getSubject().getSession().getAttribute("rand");
        if(rand == null || !rand.equals(verifyCode)){
            throw new LoginException("验证码不正确");
        }
        User user = new User(username, password);
        User user_info = loginService.queryByLogin(user);
        if(user_info == null){
            throw new LoginException("用户不存在");
        }else if(user_info.getStatus() == 0){
            throw new RuntimeException("用户已被禁用，请联系管理员");
        }else {
            String decrypt_password = DES_3.decryptBy3DES(user_info.getPassword(), user_info.getDes_key());
            if(!decrypt_password.equals(user.getPassword())){
                throw new RuntimeException("密码不正确");
            }
            // 把获取到的用户存到session中
            SecurityUtils.getSubject().getSession().setTimeout(-20000);
            SecurityUtils.getSubject().getSession().setAttribute("loginUser", user_info);
            SecurityUtils.getSubject().getSession().setAttribute("lockScreenState", false);

            // 把从数据库中查询出来的博主信息放到AuthenticationInfo中,即把正确的用户名，密码，交给shiro,再和前台输入的校验。
            AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user_info,
                    user_info.getPassword(), "authorityRealm");
            return authenticationInfo;
        }
    }
}
